package com.evl.trainOrder.service.Impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.evl.api.ticketCheckStation.service.ITicketCheckStationService;
import com.evl.common.constant.Const;
import com.evl.common.constant.OrderConst;
import com.evl.common.persistence.dao.OrderRecordMapper;
import com.evl.common.persistence.dao.TrainOrderMapper;
import com.evl.common.persistence.dao.TrainTicketMapper;
import com.evl.common.persistence.model.OrderRecord;
import com.evl.common.persistence.model.ScheduleStation;
import com.evl.common.persistence.model.StationSeatR;
import com.evl.common.persistence.model.TrainOrder;
import com.evl.common.persistence.model.TrainTicket;
import com.evl.config.properties.TravelticketsProperties;
import com.evl.constant.TrainTicketStatus;
import com.evl.dictionaryConfig.DictConfig;
import com.evl.dictionaryConfig.DictConst;
import com.evl.trainOrder.service.ITrainOrderService;
import com.evl.trainSeat.service.ITrainSeatService;
import com.evl.utils.ObjectUtil;
import com.evl.utils.filter.Filter;
import com.evl.wxpay.util.paytype.PayType;
import com.evl.wxpay.util.paytype.WxPayApi;

/**
 * <p>
 * 车票订单 服务实现类
 * </p>
 *
 * @author weijunlong
 * @since 2017-06-22
 */
@Service
public class TrainOrderServiceImpl implements ITrainOrderService {
	
	
	@Autowired
	private TrainOrderMapper trainOrderMapper;
	
	@Autowired
	private OrderRecordMapper recordMapper;
	
	@Resource
	TrainTicketMapper trainTicketMapper;
	
	@Resource
	private ITrainSeatService iTrainSeatService;
	
	@Resource
	private ITicketCheckStationService iTicketCheckStationService;
	
	@Resource
	TravelticketsProperties properties;
	
	private Logger log = Logger.getLogger(this.getClass());

	@Override
	public int addTrainOrder(TrainOrder order) throws Exception {
		//保存订单主表信息
		Integer result = trainOrderMapper.insertSelective(order);
		if(result > 0){
			OrderRecord record = new OrderRecord();
			record.setContent("生成订单");
			record.setCreateTime(new Date());
			record.setType(order.getOrderType()+"");
			record.setRecordNo(order.getOrderNo());
			recordMapper.insert(record);
		}
		//保存车票联系人信息
		return result;
	}

	@Override
	public List selectTrainOrders(TrainOrder order) {
		return ObjectUtil.toListMap(trainOrderMapper.selectTrainOrderList(order),
				new Filter(){
					public Object filtration(String fieldName,Object o){
						if(fieldName.equals("orderType")){
							Integer value = (Integer) o;
							if(value == 0){
								o = "购票";
							}else if(value == 1){
								o = "退票";
							}else if(value == 2){
								o = "改签";
							}
						}
						if(fieldName.equals("orderStatus")){
							Integer value = (Integer) o;
							if(value == 0){
								o = "未支付";
							}else if(value == 1){
								o = "已支付";
							}else if(value == 2){
								o = "支付超时自动取消";
							}else if(value == 3){
								o = "已取消";
							}
						}
						
						return o;
					}
				});
	}

	@Override
	public void updateById(TrainTicket tkModel) {
		tkModel.setStatus(String.valueOf(Const.TRAIN_TICKET_PULLIN));
		trainTicketMapper.updateById(tkModel);
	}

	@Override
	@Transactional
	public void invaliOrderList(List<TrainOrder> unPayOrderList) throws Exception{
		
		if(!unPayOrderList.isEmpty()){
			//查询车票信息
			log.debug("查询订单的车票");
			List<TrainTicket> trainTicketList = trainTicketMapper.searchTickets(unPayOrderList);
			//将同一个订单的车票信息归类
			Map<Integer,List<TrainTicket>> ticketMap = new HashMap<Integer,List<TrainTicket>>();
			for(TrainTicket trainTickes:trainTicketList){
				List<TrainTicket> orderTicketList = ticketMap.get(trainTickes.getOrderId());
				if(orderTicketList == null){
					orderTicketList = new ArrayList<TrainTicket>();
					ticketMap.put(trainTickes.getOrderId(), orderTicketList);
				}
				orderTicketList.add(trainTickes);
			}
			
			//释放座位信息
			//匹配出所有座位车站的对应数据
			List<StationSeatR> seatList = new ArrayList<StationSeatR>();
			log.debug("查询每个订单的车站，匹配车站和座位");
			for(TrainOrder trainOrder : unPayOrderList){
				List<ScheduleStation> stations = iTrainSeatService.getStationLine(trainOrder.getStaId()+"", trainOrder.getDeparture(), trainOrder.getArrive());
				List<TrainTicket> tickets = ticketMap.get(trainOrder.getId());
				if(null != tickets && tickets.size()>0){
					for(TrainTicket ticket:tickets){
						for(ScheduleStation st : stations){
							StationSeatR r = new StationSeatR();
							r.setSeatId(ticket.getSeatId());
							r.setStationId(st.getId());
							r.setSeatStatus(Const.SEAT_CHOOSABLE);
							seatList.add(r);
						}
					}
				}
			}
			log.debug("开始刷新数据");
			//释放锁定的座位
			log.debug("解锁座位");
			if(!seatList.isEmpty()){
				iTrainSeatService.releaseStationSeatR(seatList);
			}
			//增加订单流水记录
			log.debug("增加取消订单流水");
			trainOrderMapper.addUpPayRecord(unPayOrderList, "30分钟未支付系统自动撤销订单");
			//修改车票信息
			log.debug("失效车票");
			trainTicketMapper.invalidTickets(unPayOrderList);
			//修改订单信息
			log.debug("失效订单");
			trainOrderMapper.invalidOrder(unPayOrderList);
		}
	}

	@Override
	@Transactional
	public Map refushOrderPayStatus(String orderNo) throws Exception {
		log.info("更新订单状态，订单号 [" + orderNo + "]");
        TrainOrder order = trainOrderMapper.selectTrainOrderByNo(orderNo);
    	Map map = null;
    	try {
    		log.info("[" + orderNo + "]查询订单支付信息");
    		map = WxPayApi.Instance().request(order, PayType.QUERY);
			log.info("[" + orderNo + "],payInfo="+map.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
    	if(null == map){
    		return map;
    	}
		//以下字段在 status 和 result_code 都为 0的时候为支付成功
    	Object result_code = map.get("result_code");
        if ("SUCCESS".equals(result_code)) {
        	String trade_state = map.get("trade_state")==null?null:map.get("trade_state").toString();
        	if("SUCCESS".equals(trade_state)){
        		log.info("[" + orderNo + "]支付成功" );
        		String out_trade_no = map.get("out_trade_no").toString();
        		Integer total_fee = Integer.parseInt(map.get("total_fee").toString());
        		//校验支付金额是否正确
        		Integer orderPrice = (int) (order.getTotalPrice()*100);//业务系统记录单位为元
        		//避免多次重复回调
        		if(!order.getOrderStatus().equals(OrderConst.STS_PAYED)){
        			if((orderPrice - total_fee) == 0){  //一毛钱以内
        				//更新订单状态为已支付
        				trainOrderMapper.updateOrderStatus(order.getId(), OrderConst.STS_PAYED);
        				log.info("[" + orderNo + "]更新订单状态为"+OrderConst.STS_PAYED);
        				//增加订单流水
        				trainOrderMapper.addRecord(order, "支付成功", OrderConst.RECORD_TYPE_BOOK);
        				log.info("[" + orderNo + "]添加订单流水成功,fee:"+total_fee+"]");
        			}else {
        				trainOrderMapper.updateOrderStatus(order.getId(), OrderConst.STS_PAYED);
        				trainOrderMapper.addRecord(order, "支付成功,金额异常", OrderConst.RECORD_TYPE_BOOK);
        				log.info("[" + orderNo + "]订单支付成功,订单金额异常[orderPrice="+orderPrice+",total_fee="+total_fee+"]");
        			}
        			//更新车票状态
        			log.info("[" + orderNo + "]订单支付成功,更新车票信息");
        			List<TrainTicket> list = trainTicketMapper.findOrderTicketList(order.getId().toString());
        			for(TrainTicket ticket:list){
        				String qrcode = DictConfig.getKey(DictConst.qrcode_create_url)+"?ticketId="+ticket.getId();
        				ticket.setQrcode(qrcode);
        				ticket.setStatus(TrainTicketStatus.TOBEUSED.getCode()+"");
        				trainTicketMapper.updateTicketsStatusById(ticket);
        				log.info("[" + orderNo + "]订单,车票["+ticket.getId()+"]生成二维码为["+qrcode+"],更新状态为["+TrainTicketStatus.TOBEUSED.getCode()+"]");
        			}
        			//生成检票站点
        			log.info("[" + orderNo + "]创建检票站点信息");
        			iTicketCheckStationService.createCheckStations(list, order.getStaId());
        			log.info("[" + orderNo + "]支付成功,状态更新完成");
        		}
        	}else if ("NOTPAY".equals(result_code) || "USERPAYING".equals(result_code)) {
        		log.info("[" + orderNo + "]支付未成功，支付状态["+result_code+"]");
        		trainOrderMapper.updateOrderStatus(order.getId(), OrderConst.STS_SYS_PAYING);
        	}else if("PAYERROR".equals(result_code)){
        		log.info("[" + orderNo + "]支付失败，支付状态["+result_code+"]");
			}
        }else{
        	log.error("其他支付状态,status:"+map.get("trade_state"));
        }
        return map;
	}

	
}
